package com.cci.kangdao.wechatOrder.service.impl;

import com.cci.kangdao.common.RedisKeys;
import com.cci.kangdao.dao.model.UserT;
import com.cci.kangdao.redis.RedisClientUtils;
import com.cci.kangdao.service.PropertiesUtils;
import com.cci.kangdao.utilTool.LocalTimeUtil;
import com.cci.kangdao.wechatOrder.dao.UserOutSideTokenTDao;
import com.cci.kangdao.wechatOrder.dao.WeChatUserRelationTDao;
import com.cci.kangdao.wechatOrder.exception.NotCheckException;
import com.cci.kangdao.wechatOrder.model.UserOutSideTokenT;
import com.cci.kangdao.wechatOrder.model.WeChatUserRelationT;
import com.cci.kangdao.wechatOrder.service.IOutSideTokenService;
import com.cci.kangdao.wechatOrder.util.wxsdk.OutSideTokenUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * @description:
 * @author: zyf
 * @create: 2021-03-25
 */
@Service
public class OutSideTokenServiceImpl implements IOutSideTokenService {
    private Logger log = Logger.getLogger(this.getClass().getName());
    @Resource
    private OutSideTokenUtils outSideTokenUtils;
    /**
     * 用户外部Token
     */
    @Resource
    private UserOutSideTokenTDao userOutSideTokenTDao;

    @Resource
    private WeChatUserRelationTDao weChatUserRelationTDao;

    @Autowired
    private RedisClientUtils redisClientUtils;

    @Resource
    private PropertiesUtils propertiesUtils;

    @Transactional
    @Override
    public UserOutSideTokenT generateToken(UserOutSideTokenT tokenT, UserT userT) throws Exception {
        tokenT.setUserId(userT.getId()==0?null:userT.getId());
        //存在则返回新token
        outSideTokenUtils.cacheOutSideToken(userT,tokenT);

        UserOutSideTokenT oldToken = userOutSideTokenTDao.selectByOutSideIdAndUserId(tokenT.getOutSideID(), tokenT.getUserId(), tokenT.getCompanyId());

        if (oldToken == null){
            oldToken = userOutSideTokenTDao.selectByOutSideIdAndCompanyId(tokenT.getOutSideID(), tokenT.getCompanyId());
        }
        if (oldToken != null && tokenT.getId() == null){
            tokenT.setId(oldToken.getId());
        }

        if (tokenT.getId() ==null){
            tokenT.setCreator(userT.getId()==0?null:userT.getId());
            tokenT.setCreateTime(LocalTimeUtil.getRealCurrentTime());
            userOutSideTokenTDao.insert(tokenT);
        }else {
            //更新用户外部token表记录
            tokenT.setUpdator(userT.getId()==0?null:userT.getId());
            tokenT.setUpdateTime(LocalTimeUtil.getRealCurrentTime());
            if ((oldToken.getUserId() == null || oldToken.getUserId() == 0) && userT.getId()>0 ){
                tokenT.setUserId(userT.getId());
                userOutSideTokenTDao.updateTokenAndUserIdByOutSideId(tokenT);
            }else {
                userOutSideTokenTDao.updateTokenByOutSideId(tokenT);
            }
        }
        return tokenT;
    }

    @Transactional
    @Override
    public UserT getUserByWeChatToken(Long companyId, Integer type, String outSideId) throws Exception {
        String userKey = RedisKeys.outSideToken(companyId,type,outSideId);
        if (redisClientUtils.exists(userKey)){
            return (UserT) redisClientUtils.getObject(userKey);
        }
        UserT userT =  weChatUserRelationTDao.selectUserByOpenId(outSideId,companyId);
        if (userT == null){
            //throw new NotCheckException("未找到微信绑定的用户信息");
            log.error("找不到工单数据");
            return null;
        }
        return userT;
    }

    @Override
    public UserOutSideTokenT getOutSideToken(String outSideId,String token) throws Exception {
        String cacheKey =RedisKeys.tokenKey(token);
        UserOutSideTokenT tokenT = null;
        if (!redisClientUtils.exists(cacheKey)){
            tokenT = userOutSideTokenTDao.selectByToken(outSideId,token);
        }else {
            tokenT = (UserOutSideTokenT) redisClientUtils.getObject(cacheKey);
        }
        return tokenT;
    }

    @Override
    public void setCacheUser(Long companyId, Integer type, String outSideId, UserT userT) throws Exception {
        String userKey = RedisKeys.outSideToken(companyId,type,outSideId);
        if (!redisClientUtils.exists(userKey)){
            int redisCacheTime = Integer.valueOf(propertiesUtils.getPropertiesValue("redisCacheTime"));
            redisClientUtils.setObject(userKey, userT, redisCacheTime);
        }
    }

    @Override
    public void setCacheOutSideToken(String outSideId,String token,UserOutSideTokenT tokenT) throws Exception {
        String cacheKey =RedisKeys.tokenKey(token);
        if (!redisClientUtils.exists(cacheKey)){
            int redisCacheTime = Integer.valueOf(propertiesUtils.getPropertiesValue("redisCacheTime"));
            redisClientUtils.setObject(cacheKey, tokenT, redisCacheTime);
        }

    }

    @Override
    public void registerWeChatUser(String openId, String token, UserT userT, Long companyID) throws Exception {
        UserOutSideTokenT tokenT = userOutSideTokenTDao.selectByOutSideIdAndCompanyId(openId, companyID);
        WeChatUserRelationT relationT = new WeChatUserRelationT();
        WeChatUserRelationT oldRelationT = weChatUserRelationTDao.selectByOpenIdNotCompanyId(openId, companyID);
        if (oldRelationT != null){
            throw new NotCheckException("当前OPENID已经绑定用户，请重新登陆!");
        }


        if (tokenT == null){
           throw new NotCheckException("当前token为无效，请重新登陆");
        }
        tokenT.setUserId(userT.getId());
        String userKey = RedisKeys.outSideToken(companyID, tokenT.getSourceType(), openId);

        redisClientUtils.delkey(userKey);
        redisClientUtils.delkey(RedisKeys.tokenKey(token));

        setCacheUser(companyID, tokenT.getSourceType(), openId, userT);
        setCacheOutSideToken(openId,token,tokenT);
        tokenT.setUpdateTime(LocalTimeUtil.getRealCurrentTime());
        tokenT.setUpdator(userT.getId());

        relationT.setUserId(userT.getId());
        relationT.setCompanyID(companyID);
        relationT.setOpenID(openId);
        relationT.setCreateTime(LocalTimeUtil.getRealCurrentTime());
        relationT.setCreator(userT.getId());
        relationT.setFlag(0);
        weChatUserRelationTDao.insert(relationT);

        userOutSideTokenTDao.updateTokenAndUserIdByOutSideId(tokenT);

    }

    @Override
    public void replaceWeChatUser(String openId, String oldOpenId, String token, UserT userT) throws Exception {
        Long redisCacheTime = Long.valueOf(propertiesUtils.getPropertiesValue("redisCacheTime"));

        //根据token查询数据
        UserOutSideTokenT tokenT =   userOutSideTokenTDao.selectByToken(openId,token);
        //根据openId查询对应数据
        WeChatUserRelationT oldRelationT =  weChatUserRelationTDao.selectRelationTByOpenIdAndFlag(userT.getId(),oldOpenId,tokenT.getCompanyId(),0);
        //查询新openId是否存在旧数据
        WeChatUserRelationT newRelationT =  weChatUserRelationTDao.selectRelationTByOpenIdAndFlag(userT.getId(),openId,tokenT.getCompanyId(),-1);
        if (tokenT == null){
            throw  new NotCheckException("当前token无效请重新登陆");
        }

        //判断旧token是否存在
        if (oldRelationT!= null){
            oldRelationT.setUpdateTime(LocalTimeUtil.getRealCurrentTime());
            oldRelationT.setUpdator(userT.getId());
            oldRelationT.setFlag(-1);
            weChatUserRelationTDao.updateRelationTStatusByOpenId(oldRelationT);
        }

        //如果新OpenID存在数据，则更新为启用状态
        if (newRelationT!= null){
            newRelationT.setUpdateTime(LocalTimeUtil.getRealCurrentTime());
            newRelationT.setUpdator(userT.getId());
            newRelationT.setFlag(0);
            weChatUserRelationTDao.updateRelationTStatusByOpenId(newRelationT);
        }else{
            newRelationT = new WeChatUserRelationT();
            newRelationT.setUserId(userT.getId());
            newRelationT.setCompanyID(tokenT.getCompanyId());
            newRelationT.setOpenID(openId);
            newRelationT.setCreateTime(LocalTimeUtil.getRealCurrentTime());
            newRelationT.setCreator(userT.getId());

            weChatUserRelationTDao.insert(newRelationT);
        }

        //生成旧userKey
        String userKey = RedisKeys.outSideToken(tokenT.getCompanyId(), tokenT.getSourceType(), openId);

        tokenT.setOutSideID(openId);
        tokenT.setUpdator(userT.getId());
        tokenT.setUpdateTime(LocalTimeUtil.getRealCurrentTime());
        tokenT.setExpireTime(LocalTimeUtil.getRealExpireTime(redisCacheTime));
        //替换新的openid与userId的数据
        userOutSideTokenTDao.updateOutSideIDByTokenAndUserId(tokenT);
        redisClientUtils.delkey(RedisKeys.tokenKey(token));
        //替换新的
        setCacheOutSideToken(openId,token,tokenT);

        redisClientUtils.delkey(userKey);
        setCacheUser(tokenT.getCompanyId(),tokenT.getSourceType(),openId,userT);

    }
}
